home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Systemmonitors
/
Snoopy
/
Sources
/
parse.asm
< prev
next >
Wrap
Assembly Source File
|
1996-09-26
|
45KB
|
1,814 lines
incpath include:
maclib sm.mac
macfile macro.i
macfile snoopy.i
macfile macros/parse
macfile extern/main
macfile extern/misc
section main,code
ERROR_NONE equ 0
ERROR_INVALID_LINE equ 1
ERROR_INTERNAL equ 2
ERROR_NOT_ENOUGH_MEMORY equ 3
ERROR_ABORT equ 4
ASSUME_LONG equ 0
ASSUME_WORD equ 1
ASSUME_BYTE equ 2
***********************************************************************************
;-------------- parse a scriptfile with a given name. Note that this parser
;-------------- is re-entrant, which means that includes are just normal scriptfiles
;-------------- like the main scriptfile.
;--------------
;-------------- => a0: APTR filename of scriptfile
;-------------- <= d0: BOOL success
STRUCTURE psfStack,0
APTR psf_Filename
APTR psf_FileHandle
LONG psf_Line
LABEL psf_SIZEOF
ENTRY ParseScriptFile,d1-d7/a0-a6,psf_SIZEOF,a5
move.l a0,(psf_Filename,a5)
clr.b (includeLevel)
clr.l (flagSkipSimilar)
clr.l (priority)
clr.b (outputMemory)
clr.l (timeout)
clr.l (structureOffset)
move.b #ASSUME_WORD,(assume)
move.l (argNoSegTracker),d0
not.l d0
move.l d0,(flagSegTracker)
;-------------- copy command line incdir
tst.l (argIncdir)
beq.b .NOINCDIR
lea (incdirBuffer),a1
movea.l (argIncdir),a0
move.w #MAX_INCDIRNAME-1,d0
STRCPY a0,a1
.NOINCDIR
;-------------- open file
move.l (psf_Filename,a5),d1
move.l d1,(outputArgs)
move.l #MODE_OLDFILE,d2
CALL Open,dosBase
move.l d0,(psf_FileHandle,a5)
beq.b .NoFile
;-------------- read all lines one-by-one
.LOOP move.l (psf_FileHandle,a5),d1
move.l #inputMemory,d2
move.l #MAX_INPUT,d3
CALL FGets
tst.l d0
beq.b .DONE
addq.l #1,(psf_Line,a5)
move.l (psf_Line,a5),(currentLine)
bsr.b ProcessInput
tst.l d0
bne.b .FAIL
bra.b .LOOP
;-------------- FGets() returned NULL; so we have to check if it was EOF or an error
.DONE CALL IoErr
move.l d0,d1
beq.b .ReallyDone
;-------------- it WAS an error, so show it and exit
jsr ShowDosError
.FAIL move.l (psf_FileHandle,a5),d1
CALL Close
moveq #ERROR_INVALID_LINE,d0
bra.b ParseScriptFile_done
;-------------- return to sender
.ReallyDone move.l (psf_FileHandle,a5),d1
CALL Close
moveq #ERROR_NONE,d0
bra.b ParseScriptFile_done
;-------------- some error message
.NoFile lea (openfileErr,pc),a0
jsr ShowErrorMessage
moveq #ERROR_INTERNAL,d0
DONE ParseScriptFile
***********************************************************************************
;-------------- process current input data line (in 'input' buffer)
;--------------
;-------------- <= d0: BOOL success
;--------------
ENTRY ProcessInput,d1-d7/a0-a6
bsr PrepareInput
tst.b (input)
beq .DONE
;-------------- see if it is one of the codewords we need
lea (KeywordTable),a0
.CodewordLoop tst.l (a0)
beq.b .InvalidLine
;-------------- compare codeword and inputline
move.l (a0),a1
lea (input),a2
.STRICMP move.b (a1)+,d0
beq.b .Found
move.b (a2)+,d1
UCASE d1
cmp.b d1,d0
beq.b .STRICMP
.NotFound addq.l #8,a0
bra.b .CodewordLoop
;-------------- codeword found -> call function !
.Found tst.b (a2)
beq.b .FOUND
cmpi.b #"=",(a2)+
bne.b .NotFound
.FOUND tst.l (4,a0)
beq.b .DONE
move.l (4,a0),a1
movea.l a2,a0 ; a0 = start of current line
jsr a1 ; a1 = code for handler function
tst.l d0
beq.b ProcessInput_done
cmpi.l #ERROR_NOT_ENOUGH_MEMORY,d0
beq.b .NOMEMORY
;-------------- invalid input line
cmpi.l #ERROR_INVALID_LINE,d0
bne.b ProcessInput_done
.InvalidLine lea (invalidlineErr,pc),a0
bsr ParserError
bra.b ProcessInput_done
;-------------- not enough memory, display alert (because it doesn't eat up memory)
.NOMEMORY move.l #RECOVERY_ALERT,d0 ; AlertNumber
lea (memoryError,pc),a0 ; String
moveq #50,d1 ; Height
CALL DisplayAlert,intBase
moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bne.b ProcessInput_done
.DONE moveq #ERROR_NONE,d0
DONE ProcessInput
***********************************************************************************
;-------------- define a new library base
;--------------
;-------------- => a0: APTR current string position
ENTRY SetBase,d1-d7/a0-a6
;-------------- create new list entry
move.l #sbase_SIZEOF,d0
lea (bases),a1
bsr CreateEntry
tst.l d0
beq .NoMemory
;-------------- copy base
lea (sbase_Name,a5),a1
moveq #MAX_BASENAME-2,d1
.CopyBaseName move.b (a0)+,d0
beq .FAILURE
cmpi.b #",",d0
beq.b .NameFound
UCASE d0
move.b d0,(a1)+
dbra d1,.CopyBaseName
bra .BaseTooLong
.NameFound clr.b (a1)+
move.l a0,d7 ; d7 = library name
.FindEnd move.b (a0)+,d0
beq.b .EndFound
;-------------- another comma indicates the user wants to give a version description
cmpi.b #",",d0
bne.b .FindEnd
.Version clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,d6
bra.b .GoOn
;-------------- we have to remove trailing whitespaces because the library name
;-------------- is to be directly transfered to OpenLibrary() which otherwise
;-------------- could fail
.EndFound subq.l #1,a0
.WhileIsWhite cmpa.l d7,a0
beq.b .WhiteIsDone
move.b -(a0),d0
cmpi.b #" ",d0
beq.b .WhileIsWhite
cmpi.b #" ",d0
beq.b .WhileIsWhite
.WhiteIsDone clr.b (1,a0)
;-------------- now try to open the library
.GoOn movea.l d7,a1
move.l d6,d0
CALL OpenLibrary,<(execBase).w>
move.l d0,(sbase_Library,a5)
beq.b .CannotOpenLib
.DONE moveq #ERROR_NONE,d0
bra.b SetBase_done
;-------------- base name exceeds MAX_BASENAME
.BaseTooLong lea (basesizeErr,pc),a0
bra.b .SHOWERROR
;-------------- unable to OpenLibrary()
.CannotOpenLib lea (openlibErr,pc),a0
move.l d7,outputArgs+4
.SHOWERROR bsr ParserError
bra.b SetBase_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetBase_done
.FAILURE moveq #ERROR_INVALID_LINE,d0
DONE SetBase
***********************************************************************************
;-------------- define a new resource base
;--------------
;-------------- => a0: APTR current string position
ENTRY SetResource,d1-d7/a0-a6
;-------------- create new list entry
move.l #sbase_SIZEOF,d0
lea (resources),a1
bsr CreateEntry
tst.l d0
beq .NoMemory
;-------------- copy base
lea (sbase_Name,a5),a1
moveq #MAX_BASENAME-2,d1
.CopyBaseName move.b (a0)+,d0
beq .FAILURE
cmpi.b #",",d0
beq.b .NameFound
UCASE d0
move.b d0,(a1)+
dbra d1,.CopyBaseName
bra .BaseTooLong
.NameFound clr.b (a1)+
move.l a0,d7 ; d7 = library name
.FindEnd subq.l #1,a0
;-------------- we have to remove trailing whitespaces because the library name
;-------------- is to be directly transfered to OpenResource() which otherwise
;-------------- could fail
.WhileIsWhite cmpa.l d7,a0
beq.b .WhiteIsDone
move.b -(a0),d0
cmpi.b #" ",d0
beq.b .WhileIsWhite
cmpi.b #" ",d0
beq.b .WhileIsWhite
.WhiteIsDone clr.b (1,a0)
;-------------- now try to open the library
.GoOn movea.l d7,a1
CALL OpenResource,<(execBase).w>
move.l d0,(sbase_Library,a5)
beq.b .CannotOpenRes
.DONE moveq #ERROR_NONE,d0
bra.b SetBase_done
;-------------- base name exceeds MAX_BASENAME
.BaseTooLong lea (basesizeErr,pc),a0
bra.b .SHOWERROR
;-------------- unable to OpenLibrary()
.CannotOpenRes lea (openresErr,pc),a0
move.l d7,outputArgs+4
.SHOWERROR bsr ParserError
bra.b SetResource_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetResource_done
.FAILURE moveq #ERROR_INVALID_LINE,d0
DONE SetResource
***********************************************************************************
;-------------- define a new library base
;--------------
;-------------- => a0: APTR current string position
ENTRY SetDevice,d1-d7/a0-a6
;-------------- create new list entry
move.l #sdevbase_SIZEOF,d0
lea (deviceBases),a1
bsr CreateEntry
tst.l d0
beq .NoMemory
;-------------- setup list header
lea (sdevbase_Patches,a5),a1
NEWLIST a1
;-------------- creatup message port **NOT SUPPORTED YET**
;push a0
;CALL CreateMsgPort,<(execBase).w>
;pop a0
;move.l d0,(sdevbase_MsgPort,a5)
;beq .NOMSGPORT
;push a0
;movea.l d0,a1
;move.l #NULL,(LN_NAME,a1)
;CALL AddPort
;pop a0
;-------------- copy base
lea (sdevbase_Name,a5),a1
moveq #MAX_BASENAME-2,d1
.CopyBaseName move.b (a0)+,d0
beq .FAILURE
cmpi.b #",",d0
beq.b .NameFound
UCASE d0
move.b d0,(a1)+
dbra d1,.CopyBaseName
bra .BaseTooLong
.NameFound clr.b (a1)+
move.l a0,d7 ; d7 = device name
move.l #IOSTD_SIZE,(sdevbase_IOSize,a5)
move.l #-1,(sdevbase_Unit,a5) ; any unit will do
.FindEnd move.b (a0)+,d0
beq.b .EndFound
;-------------- another comma indicates the user wants to give an IO size (default=IOSTD_SIZE)
cmpi.b #",",d0
bne.b .FindEnd
clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,(sdevbase_IOSize,a5) ; set unit
;-------------- another comma indicates the user wants to give a unit (default=0)
.FindEnd2 move.b (a0)+,d0
cmpi.b #",",d0
bne.b .FindEnd
clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,(sdevbase_Unit,a5) ; set unit
bra.b .GoOn
;-------------- we have to remove trailing whitespaces because the library name
;-------------- is to be directly transfered to OpenLibrary() which otherwise
;-------------- could fail
.EndFound subq.l #1,a0
.WhileIsWhite cmpa.l d7,a0
beq.b .WhiteIsDone
move.b -(a0),d0
cmpi.b #" ",d0
beq.b .WhileIsWhite
cmpi.b #" ",d0
beq.b .WhileIsWhite
.WhiteIsDone clr.b (1,a0)
;-------------- now try to open the device
;-------------- note that what we do here is really not very smart, but it works:
;-------------- we find the device by name and "lock" it by adding an openlib count
.GoOn CALL Forbid,<(execBase).w>
movea.l d7,a1 ; name
lea (DeviceList,a6),a0 ; start
CALL FindName
move.l d0,(sdevbase_Device,a5)
beq.b .CannotOpenDev
movea.l d0,a1
addq.w #1,(LIB_OPENCNT,a1)
move.b (LIB_FLAGS,a1),d0
bset #LIBB_CHANGED,d0
move.b d0,(LIB_FLAGS,a1)
CALL SumLibrary
CALL Permit
moveq #ERROR_NONE,d0
bra.b SetDevice_done
;-------------- base name exceeds MAX_BASENAME
.BaseTooLong lea (basesizeErr,pc),a0
bra.b .SHOWERROR
;-------------- unable to OpenLibrary()
.CannotOpenDev CALL Permit
lea (opendevErr,pc),a0
move.l d7,outputArgs+4
.SHOWERROR bsr ParserError
bra.b SetDevice_done
.NOMSGPORT lea (msgportErr,pc),a0
bra.b .SHOWERROR
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetDevice_done
.FAILURE moveq #ERROR_INVALID_LINE,d0
DONE SetDevice
***********************************************************************************
;-------------- define a new offset
;--------------
;-------------- => a0: APTR current string position
ENTRY SetDefine,d1-d7/a0-a6
move.l a0,d7
;-------------- find start of offset
.FindComma move.b (a0)+,d0
beq .InvalidLine
cmpi.b #",",d0
bne.b .FindComma
clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,d6
;-------------- allocate new define
lea (defines),a1
move.l #sdef_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq.b .NoMemory
move.l d6,(sdef_Offset,a5)
lea (sdef_Name,a5),a1
movea.l d7,a0
moveq #MAX_DEFINENAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (defsizeErr,pc),a0
bsr ParserError
bra.b SetDefine_done
.InvalidLine moveq #ERROR_INVALID_LINE,d0
bra.b SetDefine_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetDefine_done
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetDefine
***********************************************************************************
;-------------- define a new offset
;--------------
;-------------- => a0: APTR current string position
ENTRY SetBitdef,d1-d7/a0-a6
move.l a0,d7
;-------------- find start of offset
.FindComma move.b (a0)+,d0
beq .InvalidLine
cmpi.b #",",d0
bne.b .FindComma
clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
moveq #0,d6
bset d0,d6
;-------------- allocate new define
lea (defines),a1
move.l #sdef_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq.b .NoMemory
move.l d6,(sdef_Offset,a5)
lea (sdef_Name,a5),a1
movea.l d7,a0
moveq #MAX_DEFINENAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (defsizeErr,pc),a0
bsr ParserError
bra.b SetBitdef_done
.InvalidLine moveq #ERROR_INVALID_LINE,d0
bra.b SetBitdef_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetBitdef_done
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetBitdef
***********************************************************************************
;-------------- include a file
;--------------
;-------------- => a0: APTR filename
STRUCTURE siStack,0
APTR sis_Handle
LONG sis_Line
LABEL sis_SIZEOF
ENTRY SetInclude,d1-d7/a0-a6,sis_SIZEOF,a4
;-------------- FIRST: try to find file in local directory
move.l a0,d1
move.l a0,d7
move.l d1,(outputArgs)
move.l #MODE_OLDFILE,d2
CALL Open,<(dosBase)>
move.l d0,(sis_Handle,a4)
bne.b .FileFound
;-------------- build includefile name
lea (incdirBuffer),a1
lea (includeName),a2
STRCPY a1,a2
;-------------- create filename
move.l #includeName,d1
move.l d7,d2
move.l #MAX_INCDIRNAME,d3
CALL AddPart
;-------------- open file
move.l #includeName,d1
move.l d1,(outputArgs+4)
move.l #MODE_OLDFILE,d2
CALL Open
move.l d0,(sis_Handle,a4)
beq.b .NoFile
;-------------- this is really not a very smart way of preventing
;-------------- "endless include loops" but it works
.FileFound cmpi.b #MAX_INCLUDELEVEL,(includeLevel)
beq.b .LEVELOVERFLOW
addq.b #1,(includeLevel)
;-------------- read all lines one-by-one
.LOOP move.l (sis_Handle,a4),d1
move.l #inputMemory,d2
move.l #MAX_INPUT,d3
CALL FGets
tst.l d0
beq.b .DONE
addq.l #1,(sis_Line,a4)
move.l (sis_Line,a4),(currentLine)
bsr ProcessInput
tst.l d0
bne.b .FAIL
bra.b .LOOP
;-------------- FGets() returned NULL; so we have to check if it was EOF or an error
.DONE CALL IoErr
move.l d0,d1
beq.b .ReallyDone
;-------------- it WAS an error, so show it and exit
jsr ShowDosError
.FAIL move.l (sis_Handle,a4),d1
CALL Close
subq.b #1,(includeLevel)
moveq #ERROR_INTERNAL,d0
bra.b SetInclude_done
;-------------- return to sender
.ReallyDone move.l (sis_Handle,a4),d1
CALL Close
subq.b #1,(includeLevel)
moveq #ERROR_NONE,d0
bra.b SetInclude_done
;-------------- too many include files
.LEVELOVERFLOW move.l (sis_Handle,a4),d1
CALL Close
lea (inclevelErr,pc),a0
bra.b .SHOWERROR
;-------------- some error message
.NoFile lea (openincErr,pc),a0
.SHOWERROR bsr ParserError
DONE SetInclude
***********************************************************************************
;-------------- set new directory for includes
;--------------
ENTRY SetIncdir,d1-d7/a0-a6
;-------------- copy name to incdir Buffer
lea (incdirBuffer),a1
move.w #MAX_INCDIRNAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (incdirsizeErr,pc),a0
bsr ParserError
bra.b SetIncdir_done
;-------------- return success
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetIncdir
**************************************************************************
;-------------- various boolean flags
SetSticky lea (argSticky),a1
bra FindBooleanKeyword
SetMatch lea (argMatch),a1
bra FindBooleanKeyword
SetTaskInfo lea (argTaskInfo),a1
bra FindBooleanKeyword
SetSegTracker lea (flagSegTracker),a1
bra FindBooleanKeyword
SetSkipSimilar lea (flagSkipSimilar),a1
bra FindBooleanKeyword
SetSkipSegNotFound
lea (flagSkipSegNotFound),a1
bra FindBooleanKeyword
***********************************************************************************
;-------------- define a new offset
;--------------
;-------------- => a0: APTR current string position
SetHide lea (hides),a1
bra SetTask
SetShow lea (shows),a1
move.b #1,(showsactive)
bra SetTask
ENTRY SetTask,d1-d7/a0-a6
;-------------- allocate new task information
move.l #stask_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq.b .NoMemory
;-------------- if it starts with a $ its assumed to be an address
cmpi.b #"$",(a0)
bne.b .ITSANAME
cmpi.b #"$",(1,a0)
bne.b .ITSAPOINTER
.ITSANAME lea (stask_Name,a5),a1
moveq #MAX_TASKNAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (tasksizeErr,pc),a0
bsr ParserError
bra.b SetTask_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetTask_done
;-------------- its a pointer; get its address
.ITSAPOINTER moveq #STVFORMAT_HEX,d0
jsr StringToValue
move.l d0,(stask_Pointer,a5)
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetTask
**************************************************************************
;-------------- display a message in the output file
;--------------
SetEcho jsr ShowEchoMessage
tst.w d0
beq .FAIL
moveq #ERROR_NONE,d0
rts
.FAIL moveq #ERROR_ABORT,d0
rts
***********************************************************************************
;-------------- define a new alias
;--------------
ENTRY SetAlias,d1-d7/a0-a6
move.l a0,d7
;-------------- find start of offset
.FindComma move.b (a0)+,d0
beq.b .InvalidLine
cmpi.b #",",d0
bne.b .FindComma
clr.b (-1,a0)
move.l a0,d6 ; d6 = TEMPLATE, d7 = ALIAS
;-------------- allocate new define
move.l #salias_SIZEOF,d0
lea (aliases),a1
bsr CreateEntry
tst.l d0
beq.b .NoMemory
;-------------- copy alias name
lea (salias_Name,a5),a1
movea.l d7,a0
moveq #MAX_ALIASNAME-1,d0
.STRCPY1 move.b (a0)+,(a1)+
beq.b .STRCPYEND1
dbra d0,.STRCPY1
lea (aliasnameErr,pc),a0
.SHOWERROR bsr ParserError
bra.b SetAlias_done
;-------------- copy alias contents
.STRCPYEND1 lea (salias_Contents,a5),a1
movea.l d6,a0
move.w #MAX_ALIASCONTENTS-1,d0
.STRCPY2 move.b (a0)+,(a1)+
beq.b .STRCPYEND2
dbra d0,.STRCPY2
lea (aliascontentErr,pc),a0
bra.b .SHOWERROR
.STRCPYEND2 moveq #ERROR_NONE,d0
bra.b SetAlias_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetAlias_done
.InvalidLine moveq #ERROR_INVALID_LINE,d0
DONE SetAlias
**************************************************************************
;--------------
ENTRY SetAssume,d1-d7/a0-a6
lea (AssumeKeys,pc),a3
.LOOP move.w (a3),d0
beq.b .FAILED
lea (AssumeKeys,pc),a4
lea (a4,d0.w),a4 ; a4 = string to match
movea.l a0,a2 ; a2 = current string
.STRICMP move.b (a4)+,d0
beq.b .Found
move.b (a2)+,d1
UCASE d1
cmp.b d1,d0
beq.b .STRICMP
.NEXT addq.l #4,a3
bra.b .LOOP
.Found move.b (a2)+,d1
beq.b .SUCCESS
cmpi.b #' ',d1
beq.b .SUCCESS
cmpi.b #' ',d1
bne.b .NEXT
.SUCCESS move.w (2,a3),d0
move.b d0,(assume)
moveq #ERROR_NONE,d0
bra.b SetAssume_done
;-------------- display warning
.FAILED move.l a0,(outputArgs+4)
lea (invassumeErr,pc),a0
bsr ParserError
DONE SetAssume
**************************************************************************
;-------------- set running priority
ENTRY SetPri
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,(priority)
moveq #ERROR_NONE,d0
DONE SetPri
**************************************************************************
;-------------- set timeout delay
ENTRY SetTimeout
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,(timeout)
moveq #ERROR_NONE,d0
DONE SetTimeout
**************************************************************************
;-------------- set output handle
ENTRY SetOutput,d1-d7/a0-a6
lea (outputMemory),a1
STRCPY a0,a1
moveq #ERROR_NONE,d0
DONE SetOutput
**************************************************************************
;-------------- define a new library snooper
;--------------
ENTRY SetWatch,d1-d7/a0-a6
;-------------- create new patch entry
move.l a0,d7
move.l #spatch_SIZEOF,d0
lea (watches),a1
bsr CreateEntry
tst.l d0
beq .NoMemory
;-------------- NEW: Setup flags
moveq #0,d0
tst.l (flagSegTracker)
bne.b .STOFF
bset #SINFOB_NOSEGTRACKER,d0
.STOFF tst.l (flagSkipSimilar)
beq.b .SSOFF
bset #SINFOB_SKIPSIMILAR,d0
.SSOFF move.l d0,(spatch_Flags,a5)
move.l (timeout),(spatch_Timeout,a5)
;-------------- try to find a base for this watch
lea (bases),a1
movea.l (LH_HEAD,a1),a1
.FindBaseLOOP tst.l (LN_SUCC,a1) ; a1 = current node
beq .NoBaseFound
lea (sbase_Name,a1),a2
movea.l d7,a0
.STRICMP move.b (a0)+,d0
UCASE d0
move.b (a2)+,d1
beq.b .BaseFound
cmp.b d1,d0
beq.b .STRICMP
movea.l (LN_SUCC,a1),a1
bra.b .FindBaseLOOP
.BaseFound move.l (sbase_Library,a1),(spatch_Library,a5)
;-------------- find Offset
movea.l d7,a0
.FindFirstComma move.b (a0)+,d0
beq .InvalidLine
cmpi.b #",",d0
bne.b .FindFirstComma
;-------------- NEW: if its not '-' or a digit, fail
cmpi.b #"-",(a0)
beq.b .ITSADIGIT
IFDIGIT (a0),.ITSADIGIT
bsr FindDefine
tst.w d0
beq.b .OffsetNotFound
move.w d1,(spatch_Offset,a5)
.SKIP_Comma cmpi.b #",",(a0)+
bne.b .SKIP_Comma
bra.b .OFFSETFOUND
.ITSADIGIT moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.w d0,(spatch_Offset,a5)
.OFFSETFOUND
;-------------- now parse the register information
bsr ParseRegisterInfo
tst d0
beq.b .InvalidLine
;-------------- the rest of this line is interpreted as the argument template
lea (spatch_Template,a5),a1
move.w #MAX_TEMPLATE-2,d0
.CopyTemplate move.b (a0)+,(a1)+
beq.b .SUCCESS
dbra d0,.CopyTemplate
lea (tempsizeErr,pc),a0
bsr ParserError
bra.b SetWatch_done
;-------------- return successfully
.SUCCESS moveq #ERROR_NONE,d0
bra.b SetWatch_done
;-------------- library base could not be found
.NoBaseFound lea (nobaseErr,pc),a0
.SHOWERROR bsr ParserError
bra.b SetWatch_done
;-------------- offset not found
.OffsetNotFound move.l a0,(outputArgs+4)
.ONFLOOP move.b (a0)+,d0
beq.b .ONFDONE
cmpi.b #",",d0
bne.b .ONFLOOP
clr.b -(a0)
.ONFDONE lea (nooffsetErr,pc),a0
bra.b .SHOWERROR
.InvalidLine moveq #ERROR_INVALID_LINE,d0
bra.b SetWatch_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
DONE SetWatch
***********************************************************************************
;-------------- read in register information stored in a syntax of
;--------------
;-------------- <register 0>/<register 1>/.../<register n>
;--------------
;-------------- where <register x> is
;--------------
;-------------- [R|B]((D|A)<0..7>)[L|W|b][:<offset>]
;--------------
;-------------- => A0: APTR start of register information
;-------------- A5: struct PatchInfo *pi
;--------------
ENTRY ParseRegisterInfo,d1-d7/a1-a6
moveq #0,d5 ; current argument counter
lea (spatch_Arguments,a5),a4 ; load register data in a4
cmpi.b #",",(a0)+
beq .EmptyReglist
subq.l #1,a0
.LOOP moveq #0,d0
;-------------- set size assumption
cmpi.b #ASSUME_BYTE,(assume)
beq .ASSUME_BYTE
cmpi.b #ASSUME_LONG,(assume)
beq .ASSUME_LONG
bra .ASSUME_WORD ; "default"
;-------------- handle register
.GetRegister move.b (a0)+,d1
beq .InvalidLine
UCASE d1
;-------------- a leading R signals that this register is a return value
cmpi.b #"R",d1
bne.b .NotReturn
bset #REGB_RESULT,d0
bra.b .GetRegister
.NotReturn
;-------------- a leading B signals that this register is a boolean value
cmpi.b #"B",d1
bne.b .NotBoolean
bset #REGB_BOOLEAN,d0
bra.b .GetRegister
.NotBoolean
;-------------- a D is for data registers
cmpi.b #"D",d1
bne.b .NotData
move.b (a0)+,d1
beq .InvalidLine
subi.b #"0",d1
andi.b #%111,d1
or.b d1,d0
bset #REGB_DATA,d0
bra.b .GetRegister
;-------------- an A stands for address registers
.NotData cmpi.b #"A",d1
bne.b .NotAddr
move.b (a0)+,d1
beq .InvalidLine
subi.b #"0",d1
andi.b #%111,d1
or.b d1,d0
bset #REGB_ADDR,d0
bra.b .GetRegister
;-------------- an I stands for address registers relative
.NotAddr cmpi.b #"I",d1
bne.b .NotRelative
move.b (a0)+,d1
beq .InvalidLine
subi.b #"0",d1
andi.b #%111,d1
or.b d1,d0
bset #REGB_INDIRECT,d0
bra .GetRegister
.NotRelative
;-------------- a trailing L stands for LONG
cmpi.b #"L",d1
bne.b .NotLong
.ASSUME_LONG bset #REGB_LONG,d0
bclr #REGB_WORD,d0
bclr #REGB_BYTE,d0
bra .GetRegister
.NotLong
;-------------- a trailing W stands for WORD
cmpi.b #"W",d1
bne.b .NotWord
.ASSUME_WORD bclr #REGB_LONG,d0
bset #REGB_WORD,d0
bclr #REGB_BYTE,d0
bra .GetRegister
.NotWord
;-------------- a trailing b stands for WORD
cmpi.b #"b",d1
bne.b .NotByte
.ASSUME_BYTE bclr #REGB_LONG,d0
bclr #REGB_WORD,d0
bset #REGB_BYTE,d0
bra .GetRegister
.NotByte
;-------------- a ':' indicates start of an offset definition
cmpi.b #":",d1
bne.b .NotOffset
pushm d1-d7/a0-a6
bsr FindDefine
tst.w d0
bne.b .FindSlash
moveq #STVFORMAT_DEC,d0
push a0
jsr StringToValue
pop d2
addq.l #1,d2
moveq #TRUE,d1
cmpa.l d2,a0
bne.b .DigitFound
moveq #FALSE,d1
.DigitFound exg.l d0,d1
.FindSlash move.l d1,(sarg_Offset,a4)
popm d1-d7/a0-a6
tst.w d0
beq.b .InvalidLine
;-------------- must be limited with a / or a ','
.FindSlashLoop move.b (a0)+,d1
beq.b .InvalidLine
cmpi.b #'/',d1
beq.b .SlashFound
cmpi.b #',',d1
beq.b .CommaFound
bra.b .FindSlashLoop
.NotOffset
;-------------- a slash / indicates the end of one register definition, so position
;-------------- to the next register slot
cmpi.b #"/",d1
bne.b .NotSlash
.SlashFound move.w d0,(a4)
lea (sarg_SIZEOF,a4),a4
addq.l #1,d5
cmpi.l #MAX_ARGUMENTS,d5
beq.b .TOOMANYARGS
bra .LOOP
.NotSlash
;-------------- a comma , indicates the end of the register list definition
cmpi.b #",",d1
bne.b .InvalidLine
.CommaFound move.w d0,(a4)
lea (sarg_SIZEOF,a4),a4
addq.l #1,d5
cmpi.l #MAX_ARGUMENTS,d5
beq .TOOMANYARGS
.EmptyReglist move.w #REG_DONE,(a4)
moveq #TRUE,d0
bra.b ParseRegisterInfo_done
.TOOMANYARGS lea (argsizeErr,pc),a0
bsr ParserError
bra.b ParseRegisterInfo_done
.InvalidLine moveq #FALSE,d0
DONE ParseRegisterInfo
**************************************************************************
;-------------- define a new device snooper
;--------------
;-------------- devcmd=<device>,<command>,<offsets>,<register list>
;--------------
;--------------
SetBeginIO moveq #SINFOF_BEGINIO,d5
bra.b HandleDevCmd
SetAbortIO moveq #SINFOF_ABORTIO,d5
bra.b HandleDevCmd
SetDevCmd moveq #SINFOF_BEGINIO|SINFOF_ABORTIO,d5
;bra.b HandleDevCmd
ENTRY HandleDevCmd,d1-d7/a0-a6
;-------------- try to find the device base for this watch
lea (deviceBases),a1
movea.l (LH_HEAD,a1),a1
move.l a0,d7
.FindBaseLOOP tst.l (LN_SUCC,a1) ; a1 = current node
beq .NoBaseFound
lea (sdevbase_Name,a1),a2
movea.l d7,a0
.STRICMP move.b (a0)+,d0
UCASE d0
move.b (a2)+,d1
beq.b .BaseFound
cmp.b d1,d0
beq.b .STRICMP
movea.l (LN_SUCC,a1),a1
bra.b .FindBaseLOOP
.BaseFound move.l (sdevbase_Device,a1),d6
;-------------- NOTE: unlike library WATCHes, DEVCMDs are stored in list
;-------------- of the device structures; this makes it later easier to
;-------------- display the device messages.
lea (sdevbase_Patches,a1),a1
move.l #spatch_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq .NoMemory
move.l d6,(spatch_Library,a5) ; (struct Device *)
;-------------- NEW: Setup flags
moveq #0,d0
or.w d5,d0
tst.l (flagSegTracker)
bne.b .STOFF
bset #SINFOB_NOSEGTRACKER,d0
.STOFF tst.l (flagSkipSimilar)
beq.b .SSOFF
bset #SINFOB_SKIPSIMILAR,d0
.SSOFF move.l d0,(spatch_Flags,a5)
;-------------- find Offset
movea.l d7,a0
.FindFirstComma move.b (a0)+,d0
beq .InvalidLine
cmpi.b #",",d0
bne.b .FindFirstComma
;-------------- NEW: if its not '-' or a digit, fail
cmpi.b #"-",(a0)
beq.b .ITSADIGIT
IFDIGIT (a0),.ITSADIGIT
bsr FindDefine
tst.w d0
beq.b .OffsetNotFound
move.w d1,(spatch_Offset,a5)
.SKIP_Comma cmpi.b #",",(a0)+
bne.b .SKIP_Comma
bra.b .OFFSETFOUND
.ITSADIGIT moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.w d0,(spatch_Offset,a5)
.OFFSETFOUND
;-------------- now parse the register information
;-------------- currently this is the same function that is used by SetWatch();
;-------------- Note that YOU SHOULD NOT USE register specifications, but rather
;-------------- statements in the form
;--------------
;-------------- .../<size>:<offset>/...
;--------------
;-------------- such as
;--------------
;-------------- .../L:IO_CMD/...
;--------------
bsr ParseRegisterInfo
tst d0
beq.b .InvalidLine
;-------------- the rest of this line is interpreted as the argument template
lea (spatch_Template,a5),a1
move.w #MAX_TEMPLATE-2,d0
.CopyTemplate move.b (a0)+,(a1)+
beq.b .SUCCESS
dbra d0,.CopyTemplate
lea (tempsizeErr,pc),a0
bsr ParserError
bra.b HandleDevCmd_done
;-------------- return successfully
.SUCCESS moveq #ERROR_NONE,d0
bra.b HandleDevCmd_done
;-------------- device base could not be found
.NoBaseFound lea (nodevbaseErr,pc),a0
.SHOWERROR bsr ParserError
bra.b HandleDevCmd_done
;-------------- offset not found
.OffsetNotFound move.l a0,(outputArgs+4)
.ONFLOOP move.b (a0)+,d0
beq.b .ONFDONE
cmpi.b #",",d0
bne.b .ONFLOOP
clr.b -(a0)
.ONFDONE lea (nooffsetErr,pc),a0
bra.b .SHOWERROR
.InvalidLine moveq #ERROR_INVALID_LINE,d0
bra.b HandleDevCmd_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
DONE HandleDevCmd
***********************************************************************************
;-------------- try to find a defined number for a function (or io command) offset
;--------------
ENTRY FindDefine,d2-d7/a0-a6
movea.l a0,a4
lea (defines),a5
movea.l (LH_HEAD,a5),a5
.LOOP tst.l (LN_SUCC,a5) ; a5 = current node
beq.b .NotInList
movea.l a4,a0 ; string to find
lea (sdef_Name,a5),a1 ; definition of String
.STRICMP move.b (a1)+,d0
beq.b .InList
move.b (a0)+,d1
cmp.b d1,d0
beq.b .STRICMP
movea.l (LN_SUCC,a5),a5
bra.b .LOOP
.InList cmpi.b #"/",(a0)+
beq.b .ISINLIST
cmpi.b #",",(-1,a0)
bne.b .NotInList
.ISINLIST moveq #TRUE,d0
move.l (sdef_Offset,a5),d1
bra.b FindDefine_done
.NotInList moveq #FALSE,d0
DONE FindDefine
**************************************************************************
;-------------- try to find the boolean value for a keyword
;--------------
;-------------- => a0: APTR string
;-------------- a1: APTR flag pointer
ENTRY FindBooleanKeyword,d1-d7/a0-a6
lea (BoolKeys,pc),a3
.LOOP move.w (a3),d0
beq.b .FAILED
lea (BoolKeys,pc),a4
lea (a4,d0.w),a4 ; a4 = string to match
movea.l a0,a2 ; a2 = current string
.STRICMP move.b (a4)+,d0
beq.b .Found
move.b (a2)+,d1
UCASE d1
cmp.b d1,d0
beq.b .STRICMP
.NEXT addq.l #4,a3
bra.b .LOOP
.Found move.b (a2)+,d1
beq.b .SUCCESS
cmpi.b #' ',d1
beq.b .SUCCESS
cmpi.b #' ',d1
bne.b .NEXT
.SUCCESS move.w (2,a3),d0
ext.l d0
move.l d0,(a1)
moveq #ERROR_NONE,d0
bra.b FindBooleanKeyword_done
;-------------- display warning
.FAILED move.l a0,(outputArgs+4)
lea (invalidboolErr,pc),a0
bsr ParserError
DONE FindBooleanKeyword
**************************************************************************
;-------------- this creates a new (internal) structure entry and adds it
;-------------- to the top of a given list
;--------------
;-------------- => d0: LONG size
;-------------- a1: APTR list header
;-------------- <= d0 = a5: APTR new entry
;--------------
ENTRY CreateEntry,d1-d7/a0-a4/a6
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
movea.l a1,a5
CALL AllocMem,<(execBase).w>
tst.l d0
beq.b CreateEntry_done
movea.l a5,a0
movea.l d0,a5
movea.l d0,a1
ADDHEAD
DONE CreateEntry
**************************************************************************
;--------------
ENTRY ParserError,d1-d7/a0-a6
lea (outputArgs),a5
push a0
move.l (currentLine),(a5)
move.l (4,a5),d7
lea (input),a0
move.l a0,(4,a5)
move.b #'.',(input+30) ; max of 30 characters
move.b #'.',(input+31)
move.b #'.',(input+32)
move.b #0,(input+33)
lea (errorHeader,pc),a0 ; format string
lea (outputArgs),a1 ; format data
lea (errorBuffer),a2 ; target string
jsr SPrintf
pop a0
move.l #errorBuffer,(a5)
move.l d7,(4,a5)
jsr ShowErrorMessage
moveq #ERROR_INTERNAL,d0
DONE ParserError
***********************************************************************************
;-------------- dealias input line
;--------------
ENTRY PrepareInput,d0-d7/a0-a6
;-------------- FIRST PASS: dealias input
lea (inputMemory),a1 ; source
lea (input),a0 ; target
.COPYINPUT move.b (a1)+,d0
beq .DONEPASS1
;-------------- if its a $ and the next character is a bracket '(', it could
;-------------- be an alias....
cmpi.b #"$",d0
bne .COPYCHAR
cmpi.b #"\\",(-2,a1)
beq .COPYCHAR
moveq #">",d7
lea (defines),a3 ; a3 = current DEFINE
cmpi.b #"<",(a1)
beq.b .DEALIASNUMERIC
moveq #")",d7
lea (aliases),a3 ; a3 = current ALIAS
cmpi.b #"(",(a1)
bne .COPYCHAR
bra.b .DEALIAS
;-------------- defines understand leading '$','%'
.DEALIASNUMERIC moveq #STVFORMAT_DEC,d6 ; current number output
cmpi.b #"$",(1,a1)
bne.b .DEALIAS
moveq #STVFORMAT_HEX,d6
addq.l #1,a1
.DEALIAS lea (1,a1),a2 ; a2 = begin of ALIAS-name
movea.l (LH_HEAD,a3),a3
.ALIASLOOP tst.l (LN_SUCC,a3)
beq .COPYCHAR
lea (salias_Name,a3),a5 ; name to match
cmpi.b #">",d7
bne.b .HANDLEALIAS
lea (sdef_Name,a3),a5 ; name to match
.HANDLEALIAS movea.l a2,a4 ; alias name
.STRCMP move.b (a4)+,d1
move.b (a5)+,d2
beq.b .EOALIAS
cmp.b d2,d1
beq.b .STRCMP
.NEXTALIAS movea.l (LN_SUCC,a3),a3
bra.b .ALIASLOOP
;-------------- end of alias name reached; call must close with ')' else its
;-------------- not a valid alias
.EOALIAS cmp.b d7,d1
bne.b .NEXTALIAS
cmpi.b #">",d7
beq.b .INSERTDEFINE
;-------------- insert contents for alias
lea (salias_Contents,a3),a3
.INSERTALIAS move.b (a3)+,(a0)+
bne.b .INSERTALIAS
subq.l #1,a0
movea.l a4,a1
bra .COPYINPUT
;-------------- insert numeric value for define
.INSERTDEFINE pushm d0-d7/a0-a6
movea.l a0,a2 ; a2=target string
lea (insertdecFormat,pc),a0 ; a0=format string
cmpi.b #STVFORMAT_HEX,d6
bne.b .USEDECFORMAT
lea (inserthexFormat,pc),a0 ; a0=format string
.USEDECFORMAT lea (outputArgs),a1 ; a1=format data
move.l (sdef_Offset,a3),(a1)
jsr SPrintf
popm d0-d7/a0-a6
.SKIPZERO tst.b (a0)+
bne.b .SKIPZERO
subq.l #1,a0
movea.l a4,a1
bra .COPYINPUT
;-------------- default: copy char
.COPYCHAR move.b d0,(a0)+
bra .COPYINPUT
.DONEPASS1 clr.b (a0)+
;-------------- (END OF FIRST PASS)
;-------------- PASS TWO: remove comments, skip trailing whitespaces
;-------------- remove comments and NEWLINE
lea (input),a0
cmpi.b #COMMENT_LINE,(a0) ; skip if its a comment line
beq.b .SKIPLINE
.CommentLoop move.b (a0)+,d0
beq.b .CommentDone
cmpi.b #"\\",d0
beq.b .EscapeChar
cmpi.b #COMMENT,d0
beq.b .CommentFound
cmpi.b #"\n",d0
bne.b .CommentLoop
.CommentFound clr.b -(a0)
.CommentDone
;-------------- skip the line if it only consists of whitespaces
lea (input),a0
.WhitespaceLoop move.b (a0)+,d0
beq.b .SKIPLINE
cmpi.b #" ",d0
beq.b .WhitespaceLoop
cmpi.b #" ",d0
beq.b .WhitespaceLoop
.NotWhitespaces bra.b PrepareInput_done
;-------------- skip whole line
.SKIPLINE clr.b (input)
bra.b PrepareInput_done
;-------------- new: support escape characters \\,\n,\t,\e,\;,\$
.EscapeChar move.b (a0),d1
;-------------- '\;' results in ';'
moveq #';',d0
cmpi.b #';',d1
beq.b .deleteChar
;-------------- '\n' results in '<NEWLINE>'
moveq #10,d0
cmpi.b #'n',d1
beq.b .deleteChar
;-------------- '\e' results in '<ESC>'
moveq #'',d0
cmpi.b #'e',d1
beq.b .deleteChar
;-------------- '\\' results in '\'
moveq #'\\',d0
cmpi.b #'\\',d1
beq.b .deleteChar
;-------------- '\$' results in '$'
moveq #'$',d0
cmpi.b #'$',d1
beq.b .deleteChar
;-------------- '\t' results in '<TAB>'
moveq #8,d0
cmpi.b #'\t',d1
beq.b .deleteChar
bra.b .CommentLoop
.deleteChar lea (-1,a0),a1 ; a1=where the former '\' was placed
move.b d0,(a1)+
addq.l #1,a0
push a0
.DELETECOPY move.b (a0)+,(a1)+
bne.b .DELETECOPY
pop a0
subq.l #1,a0
bra.b .CommentLoop
DONE PrepareInput
**************************************************************************
;-------------- add SHOW statements given in the command line
;--------------
ENTRY SetCmdlineSHOWs,d0-d7/a0-a6
move.l (argShow),d0
beq.b .DONE
movea.l d0,a4
.LOOP move.l (a4)+,d1
beq.b .DONE
move.l #stask_SIZEOF,d0
lea (shows),a1
bsr CreateEntry
tst d0
beq.b SetCmdlineSHOWs_done
movea.l d1,a0
move.b #1,(showsactive)
;-------------- if it starts with a $ its assumed to be an address
cmpi.b #"$",(a0)
bne.b .ITSANAME
cmpi.b #"$",(1,a0)
bne.b .ITSAPOINTER
.ITSANAME lea (stask_Name,a5),a1
moveq #MAX_TASKNAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (tasksizeErr,pc),a0
jsr ParserError
bra.b SetCmdlineSHOWs_done
;-------------- its a pointer; get its address
.ITSAPOINTER moveq #STVFORMAT_HEX,d0
jsr StringToValue
move.l d0,(stask_Pointer,a5)
.STRCPYEND moveq #ERROR_NONE,d0
bra.b .LOOP
.DONE moveq #ERROR_NONE,d0
DONE SetCmdlineSHOWs
***********************************************************************************
;-------------- structure macro:
;--------------
;-------------- STRUCTURE <NAME>,<SIZE>
;--------------
;-------------- => a0: APTR current string position
SetStructure moveq #FALSE,d5
bra.b SetSTRUCTURE
SetSTRUCT moveq #TRUE,d5
;bra.b SetSTRUCTURE
ENTRY SetSTRUCTURE,d1-d7/a0-a6
move.l a0,d7
;-------------- find start of offset
.FindComma move.b (a0)+,d0
beq .InvalidLine
cmpi.b #",",d0
bne.b .FindComma
clr.b (-1,a0)
moveq #STVFORMAT_DEC,d0
jsr StringToValue
move.l d0,d6
;-------------- allocate new define
lea (defines),a1
move.l #sdef_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq.b .NoMemory
tst.w d5
beq.b .SetStructure
move.l (structureOffset),(sdef_Offset,a5)
add.l d6,(structureOffset)
bra.b .SetContinue
.SetStructure move.l #0,(sdef_Offset,a5) ; not d6!!!!!!!!!!!!!!!!!!!!!!!!
move.l d6,(structureOffset)
.SetContinue lea (sdef_Name,a5),a1
movea.l d7,a0
moveq #MAX_DEFINENAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (defsizeErr,pc),a0
bsr ParserError
bra.b SetSTRUCTURE_done
.InvalidLine moveq #ERROR_INVALID_LINE,d0
bra.b SetSTRUCTURE_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetSTRUCTURE_done
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetSTRUCTURE
***********************************************************************************
;-------------- set structure entry
;--------------
;-------------- <element> <NAME>
;--------------
;-------------- => a0: APTR current string position
;-------------- d6: LONG structure size increment
SetLONG moveq #4,d6
bra.b SetStructureElement
SetWORD moveq #2,d6
bra.b SetStructureElement
SetBYTE moveq #1,d6
bra.b SetStructureElement
SetLABEL moveq #0,d6
;bra.b SetStructureElement
ENTRY SetStructureElement,d1-d7/a0-a6
move.l a0,d7
;-------------- skip trailing whitespaces
.STRIPWS move.b (a0)+,d0
beq.b .STRIPPED
cmpi.b #" ",d0
beq.b .STRIP
cmpi.b #" ",d0
bne.b .STRIPWS
.STRIP clr.b (-1,a0)
.STRIPPED
;-------------- allocate new define
lea (defines),a1
move.l #sdef_SIZEOF,d0
bsr CreateEntry
tst.l d0
beq.b .NoMemory
move.l (structureOffset),(sdef_Offset,a5) ; not d6!!!!!!!!!!!!!!!!!!!!!!!!
add.l d6,(structureOffset)
lea (sdef_Name,a5),a1
movea.l d7,a0
moveq #MAX_DEFINENAME-1,d0
.STRCPY move.b (a0)+,(a1)+
beq.b .STRCPYEND
dbra d0,.STRCPY
;-------------- error, define name too long
lea (defsizeErr,pc),a0
bsr ParserError
bra.b SetStructureElement_done
.NoMemory moveq #ERROR_NOT_ENOUGH_MEMORY,d0
bra.b SetStructureElement_done
.STRCPYEND moveq #ERROR_NONE,d0
DONE SetStructureElement
SetALIGNWORD move.l (structureOffset),d0
BRBC.B #0,d0,.ISEVEN
addq.l #1,(structureOffset)
.ISEVEN moveq #ERROR_NONE,d0
rts
SetALIGNLONG move.l (structureOffset),d0
BRBC.B #0,d0,.ISEVEN
addq.l #1,d0
.ISEVEN BRBC.B #1,d0,.ISLONG
addq.l #2,d0
.ISLONG move.l d0,(structureOffset)
moveq #ERROR_NONE,d0
rts
;-------------- The keyword table describes which commands Snoopy understands.
;-------------- NOTE: You can define your personal keyword aliases by adding
;-------------- statements that only have a different second argument; example:
;--------------
;-------------- keyword Base,LIBRARY
;--------------
;-------------- will define the new keyword LIBRARY that is exactly the same as Base
;-------------- Define your own keyword handling functions as Set<Name> (SetBase in
;-------------- the example above)
KeywordTable keyword RESET
keyword Base,BASE
keyword Watch,WATCH
keyword Watch,SNOOP ; synonym for WATCH
keyword Hide,HIDE
keyword Pri,PRI
keyword Show,SHOW
keyword Define,DEFINE
keyword Bitdef,BITDEF
keyword Include,INCLUDE
keyword Incdir,INCDIR
keyword Output,OUTPUT
keyword Sticky,STICKY
keyword Match,MATCH
keyword TaskInfo,TASKINFO
keyword SegTracker,SEGTRACKER
keyword Alias,ALIAS
keyword Assume,ASSUME
keyword Echo,ECHO
keyword Echo,PRINT
keyword Device,DEVICE
keyword DevCmd,DEVCMD
keyword BeginIO,BEGINIO
keyword AbortIO,ABORTIO
keyword Resource,RESOURCE
keyword SkipSimilar,SKIPSIMILAR
keyword Timeout,DELAY
;-------------- structure macros
keyword Structure,STRUCTURE
keyword LONG,APTR
keyword LONG,CPTR
keyword LONG,FPTR
keyword LONG,LONG
keyword LONG,ULONG
keyword LONG,FLOAT
keyword WORD,BOOL
keyword WORD,RPTR
keyword WORD,WORD
keyword WORD,UWORD
keyword WORD,SHORT
keyword WORD,USHORT
keyword BYTE,BYTE
keyword BYTE,UBYTE
keyword LABEL,LABEL
keyword STRUCT,STRUCT
keyword ALIGNWORD,ALIGNWORD
keyword ALIGNLONG,ALIGNLONG
;-------------- the following options are not documented (yet); they will be fully
;-------------- introduced in the next versions (guess what they are about)
keyword SkipSegNotFound,SKIPSEGNOTFOUND
keyword DONE
BoolKeys dc.w .1-BoolKeys,TRUE
dc.w .2-BoolKeys,TRUE
dc.w .3-BoolKeys,TRUE
dc.w .4-BoolKeys,TRUE
dc.w .5-BoolKeys,FALSE
dc.w .6-BoolKeys,FALSE
dc.w .7-BoolKeys,FALSE
dc.w .8-BoolKeys,FALSE
dc.w .9-BoolKeys,TRUE
dc.w .10-BoolKeys,FALSE
dc.w 0
.1 cstr "YES"
.2 cstr "TRUE"
.3 cstr "ON"
.4 cstr "ACTIVE"
.5 cstr "NO"
.6 cstr "FALSE"
.7 cstr "OFF"
.8 cstr "NOT ACTIVE"
;-------------- hey! you found out about these! Don't tell everybody! ;-)
.9 cstr "FUNKY"
.10 cstr "SHIT"
even
AssumeKeys dc.w .1-AssumeKeys,ASSUME_LONG
dc.w .2-AssumeKeys,ASSUME_WORD
dc.w .3-AssumeKeys,ASSUME_BYTE
dc.w 0
.1 cstr "LONG"
.2 cstr "WORD"
.3 cstr "BYTE"
even
memoryError DEFINE_ALERT <FATAL ERROR, not enough memory available>
insertdecFormat cstr '%ld'
inserthexFormat cstr '%lx'
openfileErr cstr 'ERROR, cannot open scriptfile "%s"'
;-------------- error strings supported by this module
errorHeader cstr 'ERROR in line %ld: "%s"\n'
invalidlineErr cstr '%sunknown commands or invalid input line\n'
openlibErr cstr '%scannot open library "%s"'
openresErr cstr '%scannot open resource "%s"'
opendevErr cstr '%scannot open device "%s"'
basesizeErr cstr '%sbase shortcut too long (max=',_VALOF(MAX_BASENAME),')'
defsizeErr cstr '%sdefine name too long (max=',_VALOF(MAX_DEFINENAME),')'
inclevelErr cstr '%sinclude level overflow (max=',_VALOF(MAX_INCLUDELEVEL),')'
openincErr cstr '%scannot open includefile "%s"'
incdirsizeErr cstr '%sincdir name too long (max=',_VALOF(MAX_INCDIRNAME),')'
tasksizeErr cstr '%staskname too long (max=',_VALOF(MAX_TASKNAME),')'
invalidboolErr cstr '%sinvalid boolean expression "%s"'
aliasnameErr cstr '%salias name too long (max=',_VALOF(MAX_ALIASNAME),')'
aliascontentErr cstr '%salias contents too long (max=',_VALOF(MAX_ALIASCONTENTS),')'
invassumeErr cstr '%sinvalid assumption "%s"'
tempsizeErr cstr '%stemplate too long (max=',_VALOF(MAX_TEMPLATE),')'
nobaseErr cstr '%scannot find library base for this definition'
nodevbaseErr cstr '%scannot find device base for this definition'
nooffsetErr cstr '%soffset "%s" not defined'
argsizeErr cstr '%stoo many output arguments (max=',_VALOF(MAX_ARGUMENTS),')'
msgportErr cstr '%scannot allocate message port'
section memory,bss
currentLine ds.l 1
defs.l outputArgs,256
defs.b inputMemory,<(MAX_INPUT+2)>
input ds.b MAX_INPUT+2
defs.b outputMemory,MAX_INPUT+2
incdirBuffer ds.b MAX_INCDIRNAME
includeName ds.b MAX_INCDIRNAME
includeLevel ds.b 1
assume ds.b 1
even
errorBuffer ds.b MAX_INPUT+80
defs.l flagSegTracker,1
defs.l flagSkipSimilar,1
defs.l flagSkipSegNotFound,1
defs.l timeout,1
defs.l priority,1
defs.l structureOffset,1
end
;-------------- ecstasy mutherfuckers! the future is before your eyes!
**************************************************************************
;--------------